{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "##-----------------------------------------##\n",
    "#               Packages\n",
    "##-----------------------------------------##\n",
    "import dash_bootstrap_components as dbc\n",
    "from datetime import datetime as dt\n",
    "import dash\n",
    "import dash_html_components as html\n",
    "import dash_core_components as dcc\n",
    "from dash.dependencies import Input, Output\n",
    "import dash_table\n",
    "import dash_leaflet as dl\n",
    "from dash.dependencies import Output, Input\n",
    "\n",
    "from IPython.display import Image\n",
    "from IPython.display import display\n",
    "import ipywidgets as widgets\n",
    "\n",
    "import ee\n",
    "from datetime import date\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import geopandas as gpd\n",
    "import matplotlib.pyplot as plt\n",
    "from shapely.geometry import Point\n",
    "\n",
    "#import eeconvert # Package to conver Earth Engine collection to dataframe or geodataframe\n",
    "import json\n",
    "\n",
    "import plotly.graph_objects as go\n",
    "from plotly.subplots import make_subplots\n",
    "import plotly.express as px\n",
    "\n",
    "\n",
    "# Earth Engine Python API\n",
    "ee.Initialize()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Serving Flask app \"__main__\" (lazy loading)\n",
      " * Environment: production\n",
      "\u001b[31m   WARNING: This is a development server. Do not use it in a production deployment.\u001b[0m\n",
      "\u001b[2m   Use a production WSGI server instead.\u001b[0m\n",
      " * Debug mode: off\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " * Running on http://127.0.0.1:8150/ (Press CTRL+C to quit)\n",
      "127.0.0.1 - - [14/Apr/2020 11:46:45] \"\u001b[37mGET / HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:46:45] \"\u001b[37mGET /_dash-layout HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:46:45] \"\u001b[37mGET /_dash-dependencies HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:46:45] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:46:45] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:46:45] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:46:45] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Exception on /_dash-update-component [POST]\n",
      "Traceback (most recent call last):\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 2446, in wsgi_app\n",
      "    response = self.full_dispatch_request()\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 1951, in full_dispatch_request\n",
      "    rv = self.handle_user_exception(e)\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 1820, in handle_user_exception\n",
      "    reraise(exc_type, exc_value, tb)\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/_compat.py\", line 39, in reraise\n",
      "    raise value\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 1949, in full_dispatch_request\n",
      "    rv = self.dispatch_request()\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 1935, in dispatch_request\n",
      "    return self.view_functions[rule.endpoint](**req.view_args)\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/dash/dash.py\", line 1407, in dispatch\n",
      "    response.set_data(self.callback_map[output][\"callback\"](*args))\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/dash/dash.py\", line 1294, in add_context\n",
      "    output_value = func(*args, **kwargs)  # %% callback invoked %%\n",
      "  File \"<ipython-input-3-526213b9eb63>\", line 213, in update_output\n",
      "    end_date = dt.strptime(end_date.split('T')[0], '%Y-%m-%d')\n",
      "AttributeError: 'NoneType' object has no attribute 'split'\n",
      "Exception on /_dash-update-component [POST]\n",
      "Traceback (most recent call last):\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 2446, in wsgi_app\n",
      "    response = self.full_dispatch_request()\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 1951, in full_dispatch_request\n",
      "    rv = self.handle_user_exception(e)\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 1820, in handle_user_exception\n",
      "    reraise(exc_type, exc_value, tb)\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/_compat.py\", line 39, in reraise\n",
      "    raise value\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 1949, in full_dispatch_request\n",
      "    rv = self.dispatch_request()\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/flask/app.py\", line 1935, in dispatch_request\n",
      "    return self.view_functions[rule.endpoint](**req.view_args)\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/dash/dash.py\", line 1407, in dispatch\n",
      "    response.set_data(self.callback_map[output][\"callback\"](*args))\n",
      "  File \"/Users/nat/opt/anaconda3/envs/thesis/lib/python3.7/site-packages/dash/dash.py\", line 1294, in add_context\n",
      "    output_value = func(*args, **kwargs)  # %% callback invoked %%\n",
      "  File \"<ipython-input-3-526213b9eb63>\", line 213, in update_output\n",
      "    end_date = dt.strptime(end_date.split('T')[0], '%Y-%m-%d')\n",
      "AttributeError: 'NoneType' object has no attribute 'split'\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "127.0.0.1 - - [14/Apr/2020 11:46:48] \"\u001b[35m\u001b[1mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 500 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:47:19] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:47:26] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:47:26] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:47:29] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:47:31] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:47:32] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:47:32] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n",
      "127.0.0.1 - - [14/Apr/2020 11:47:33] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Your inputs return 342 images\n",
      "                NDWI       Time\n",
      "time_stamp                     \n",
      "2000-12-31  0.688477 2000-12-31\n",
      "2001-12-31  0.685324 2001-12-31\n",
      "2002-12-31  0.719874 2002-12-31\n",
      "2003-12-31  0.571947 2003-12-31\n",
      "2004-12-31  0.701617 2004-12-31\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "127.0.0.1 - - [14/Apr/2020 11:47:49] \"\u001b[37mPOST /_dash-update-component HTTP/1.1\u001b[0m\" 200 -\n"
     ]
    }
   ],
   "source": [
    "##-----------------------------------------##\n",
    "#               Collection Attributes\n",
    "##-----------------------------------------##\n",
    "\n",
    "\n",
    "def makeLandsatSeries():\n",
    "\n",
    "    lt4 = ee.ImageCollection('LANDSAT/LT04/C01/T1_SR')\n",
    "    lt5 = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')\n",
    "    le7 = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR')\n",
    "    lc8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')\n",
    "\n",
    "    lt4 = lt4.select(['B1','B2','B3','B4','B5','B7','pixel_qa'],['blu','grn','red','nir','swir1','swir2','pixel_qa'])\n",
    "    lt5 = lt5.select(['B1','B2','B3','B4','B5','B7','pixel_qa'],['blu','grn','red','nir','swir1','swir2','pixel_qa'])\n",
    "    le7 = le7.select(['B1','B2','B3','B4','B5','B7','pixel_qa'],['blu','grn','red','nir','swir1','swir2','pixel_qa'])\n",
    "    lc8 = lc8.select(['B2','B3','B4','B5','B6','B7','pixel_qa'],['blu','grn','red','nir','swir1','swir2','pixel_qa'])\n",
    "\n",
    "    fullCollection = ee.ImageCollection(lt4.merge(lt5).merge(le7).merge(lc8))\n",
    "    return fullCollection\n",
    "\n",
    "\n",
    "##-----------------------------------------##\n",
    "#               Mapbox Attributes\n",
    "##-----------------------------------------##\n",
    "\n",
    "external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css',\n",
    "'https://codepen.io/chriddyp/pen/brPBPO.css']\n",
    "\n",
    "\n",
    "# Mapbox setup\n",
    "mapbox_url = \"https://api.mapbox.com/styles/v1/mapbox/{id}/tiles/{{z}}/{{x}}/{{y}}{{r}}?access_token={access_token}\"\n",
    "mapbox_token = 'pk.eyJ1IjoibmF0MSIsImEiOiJjazhpeDdwZ3gwM3FyM2RueTZwdDJ0bzB2In0.lqoQJb90lcn0cu-zulXWyw'\n",
    "mapbox_ids = [\"light-v9\", \"dark-v9\", \"streets-v9\", \"outdoors-v9\", \"satellite-streets-v9\"]\n",
    "\n",
    "# Element mapbox_ids\n",
    "BASE_LAYER_ID = \"base-layer-id\"\n",
    "BASE_LAYER_DROPDOWN_ID = \"base-layer-drop-down-id\"\n",
    "MAP_ID = \"map-id\"\n",
    "MARKER = \"marker-id\"\n",
    "NEW_MARKER= \"new-marker-id\"\n",
    "COORDINATE_CLICK_ID = \"coordinate-click-id\"\n",
    "\n",
    "\n",
    "##-----------------------------------------##\n",
    "#               Functions\n",
    "##-----------------------------------------##\n",
    "\n",
    "\n",
    "\n",
    "app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])\n",
    "\n",
    "controls = dbc.Card(\n",
    "    [   \n",
    "        dbc.FormGroup(\n",
    "            [\n",
    "                dbc.Label(\"Base Layers\"),\n",
    "                dcc.Dropdown(\n",
    "                    id=BASE_LAYER_DROPDOWN_ID,\n",
    "                    options=[\n",
    "                        {\"label\": i, \"value\": mapbox_url.format(id=i, access_token=mapbox_token)} for i in mapbox_ids\n",
    "                    ],\n",
    "                    value=mapbox_url.format(id=\"light-v9\", access_token=mapbox_token)\n",
    "                ),\n",
    "            ]\n",
    "        ),\n",
    "        \n",
    "        dbc.FormGroup(\n",
    "            [\n",
    "                dbc.Label(\"Cloud\"),\n",
    "                dbc.Input(id=\"cloud\", type=\"number\", min = 0, max = 100, step = 10,),\n",
    "            ]\n",
    "        ),\n",
    "        html.Div(id=\"number-out\"),\n",
    "        \n",
    "        dbc.FormGroup(\n",
    "            [\n",
    "                dbc.Label(\"Date\"),\n",
    "                dcc.DatePickerRange(\n",
    "                    id='my-date-picker-range',\n",
    "                    #month_format='Do MMM, YYYY',\n",
    "                    display_format=\"YYYY,MM,DD\",\n",
    "                    min_date_allowed=dt(1995,1,1),\n",
    "                    max_date_allowed=dt.today(),\n",
    "                    #initial_visible_month=dt(2017, 8, 5),\n",
    "                    start_date=dt(2000,1,1),\n",
    "                    #end_date=dt.today(),\n",
    "                    start_date_placeholder_text=\"YYYY,MM,DD\",\n",
    "                    end_date_placeholder_text=\"YYYY,MM,DD\",\n",
    "                ),\n",
    "                html.Div(id='output-container-date-picker-range')\n",
    "            ]\n",
    "        )\n",
    "        \n",
    "    ],\n",
    "    body=True,\n",
    ")\n",
    "\n",
    "#html.P(\"Coordinate (click on map):\"),\n",
    "#html.Div(id=COORDINATE_CLICK_ID),\n",
    "#fluid=True,\n",
    "app.layout = dbc.Container(\n",
    "    [\n",
    "        html.H1(\"Satellite Analysis\"),\n",
    "        html.Hr(),\n",
    "        dbc.Row(\n",
    "            [\n",
    "                dbc.Col(dl.Map(id=MAP_ID,\n",
    "                               style={'width': '1000px', 'height': '500px'},\n",
    "                               center=[-13, 48],\n",
    "                               zoom = 5,\n",
    "                               children=[\n",
    "                                   dl.TileLayer(id=BASE_LAYER_ID),\n",
    "                                   dl.Marker(id=MARKER, position=[56, 9.8], interactive=True,   opacity=0.8),\n",
    "                                   html.Div(id=NEW_MARKER),\n",
    "                                   html.Div(id=COORDINATE_CLICK_ID)\n",
    "                               ])),\n",
    "                \n",
    "                dbc.Col(controls),\n",
    "            \n",
    "            ],),\n",
    "    ],\n",
    ")\n",
    "\n",
    "\n",
    "# MARKER\n",
    "@app.callback(Output(NEW_MARKER, 'children'),\n",
    "              [Input(MAP_ID, 'click_lat_lng')])\n",
    "def new_marker(x):\n",
    "    if x is not None:\n",
    "\n",
    "        global lat\n",
    "        global lon\n",
    "        lat, lon = x\n",
    "        #print(\"Marker:\", lat)\n",
    "\n",
    "        return dl.Marker(position=[lat, lon])\n",
    "    else:\n",
    "        return None\n",
    "\n",
    "# COORDINATES\n",
    "@app.callback(Output(COORDINATE_CLICK_ID, 'children'),\n",
    "              [Input(MAP_ID, 'click_lat_lng')])\n",
    "def click_coord(e):\n",
    "    if e is not None:\n",
    "        #print(\"Click:\", json.dumps(e))\n",
    "        return json.dumps(e)\n",
    "    else:\n",
    "        return \"-\"\n",
    "\n",
    "# BASE LAYER\n",
    "@app.callback(Output(BASE_LAYER_ID, \"url\"),\n",
    "              [Input(BASE_LAYER_DROPDOWN_ID, \"value\")])\n",
    "def set_baselayer(url):\n",
    "    return url\n",
    "\n",
    "\n",
    "# CLOUD\n",
    "@app.callback(\n",
    "Output(\"number-out\", \"children\"),\n",
    "[Input(\"cloud\", \"value\")\n",
    "],) \n",
    "\n",
    "def number_render(cloud):\n",
    "\n",
    "    if lat is not None:\n",
    "\n",
    "        global latitude\n",
    "        latitude = lat\n",
    "\n",
    "        global longitude\n",
    "        longitude = lon\n",
    "\n",
    "        global Maxcloud\n",
    "        Maxcloud = cloud \n",
    "        point = {'type':'Point', 'coordinates':[longitude, latitude]}; # This point is on turbid water\n",
    "\n",
    "        #print(\"Cloud lat:\",lat, \"Type:\", type(lat))\n",
    "        #print(\"Cloud latitude:\",latitude, \"Type:\", type(latitude))\n",
    "        return ()\n",
    "\n",
    "# DATE\n",
    "@app.callback(\n",
    "dash.dependencies.Output('output-container-date-picker-range', 'children'),\n",
    "[dash.dependencies.Input('my-date-picker-range', 'start_date'),\n",
    " dash.dependencies.Input('my-date-picker-range', 'end_date')\n",
    "])\n",
    "\n",
    "def update_output(start_date, end_date):\n",
    "\n",
    "    # Define point\n",
    "    point = {'type':'Point', 'coordinates':[longitude, latitude]}; # This point is on turbid water\n",
    "    #print(\"Update Output Point\", point)\n",
    "\n",
    "    # Define Full Collection\n",
    "    fullCollection= makeLandsatSeries()\n",
    "\n",
    "    # Filter collection by Lat, Lon & Cloud\n",
    "    filtered = fullCollection.filterBounds(ee.Geometry.Point(longitude,latitude)).filter(ee.Filter.lt('CLOUD_COVER', Maxcloud))\n",
    "\n",
    "    #Count Size // Total number of images: 165\n",
    "    count = int(filtered.size().getInfo())\n",
    "    #print(\"Update Output Count:\", count)\n",
    "\n",
    "    #Info\n",
    "    info = filtered.getRegion(point,500).getInfo()\n",
    "\n",
    "\n",
    "    if start_date is not None:\n",
    "        start_date = dt.strptime(start_date.split('T')[0], '%Y-%m-%d')\n",
    "        start_date_string = start_date.strftime('%Y-%m-%d')\n",
    "        startDate = start_date_string\n",
    "\n",
    "        end_date = dt.strptime(end_date.split('T')[0], '%Y-%m-%d')\n",
    "        end_date_string = end_date.strftime('%Y-%m-%d')\n",
    "        endDate = end_date_string\n",
    "        \n",
    "        #print(\"strptime: \", end_date)\n",
    "        #print(\"end string: \", end_date_string)\n",
    "        #print(\"endDate: \", endDate)\n",
    "\n",
    "        # Filter Collection with Lat, Lon & Cloud\n",
    "        filtered2 = filtered.filterDate(startDate, endDate)\n",
    "\n",
    "        #Count Size // Total number of images:\n",
    "        count = int(filtered2.size().getInfo())\n",
    "        print(\"Your inputs return\", count, \"images\")\n",
    "\n",
    "        info = filtered2.getRegion(point,500).getInfo()\n",
    "\n",
    "        # Datframe\n",
    "        df = pd.DataFrame(info,columns = ['id', 'longitude', 'latitude', 'time', 'blu', 'grn', 'red', 'nir', 'swir1', 'swir2', 'pixel_qa'])\n",
    "        #df = df.to_json(date_format='iso', orient='split')\n",
    "\n",
    "        # Create an ID column with NAN values\n",
    "        df['Satellite_ID'] = ('NAN')\n",
    "\n",
    "        # Make sure that all NaN values are `np.nan` not `'NAN'` (strings)\n",
    "        df = df.replace('NAN', np.nan)\n",
    "        mask = df['id'].str.contains(r'LT04')\n",
    "        df.loc[mask, 'Satellite_ID'] = ('L4')\n",
    "\n",
    "        mask = df['id'].str.contains(r'LT05')\n",
    "        df.loc[mask, 'Satellite_ID'] = ('L5')\n",
    "\n",
    "        mask = df['id'].str.contains(r'LT05')\n",
    "        df.loc[mask, 'Satellite_ID'] = ('L5')\n",
    "\n",
    "        mask = df['id'].str.contains(r'LE07')\n",
    "        df.loc[mask, 'Satellite_ID'] = ('L7')\n",
    "\n",
    "        mask = df['id'].str.contains(r'LC08')\n",
    "        df.loc[mask, 'Satellite_ID'] = ('L8')\n",
    "\n",
    "        # Drop First row (a duplicate of column header)\n",
    "        df = df.drop(df.index[0])\n",
    "\n",
    "        # The Earth Engine time stamp in milliseconds since the UNIX epoch.\n",
    "        # Link GEE: https://developers.google.com/earth-engine/glossary\n",
    "\n",
    "        # Convert UNIX to datetime\n",
    "        # Use pd.to_datetime() to convert unix epoch time\n",
    "        # Result is like this: 1994-03-17 06:11:20.254\n",
    "        df['time_stamp'] = pd.to_datetime(df['time'], unit='ms')\n",
    "\n",
    "        # Convert to String inorder to apply string split\n",
    "        df['time_string'] = df['time_stamp'].astype(str)\n",
    "\n",
    "        # make the new date column using string indexing [0:10] will give us the year,month,date part\n",
    "        # Result is like this 1994-03-17\n",
    "        df['Date'] = df['time_string'].str[0:10]\n",
    "\n",
    "        # Convert back to datetime\n",
    "        df['Date'] = pd.to_datetime(df['Date'])\n",
    "\n",
    "        # Drop unnecessary columns\n",
    "        #df = df.drop('time_stamp', axis=1)\n",
    "        df = df.drop('time_string', axis=1)\n",
    "\n",
    "        # Sort by Date\n",
    "        df = df.sort_values(by='Date')\n",
    "        \n",
    "\n",
    "        # Calculate NDWI\n",
    "        #ndwi = (green - swir) / (green + swir)\n",
    "        df['NDWI'] = (df['grn'] - df['swir1']) / (df['grn'] + df['swir1'])\n",
    "        df['NDWI'] = pd.to_numeric(df['NDWI'])\n",
    "        \n",
    "        # Set Index\n",
    "        df = df.set_index('time_stamp')\n",
    "        #print(\"Original DF: \", df)\n",
    "\n",
    "        # Simplified Table for Dash\n",
    "        #simple_df = df[['NDWI', 'Date']].copy()\n",
    "        \n",
    "    \n",
    "        # New Dataframe: Set Mean NDWI & Time columns. Time column is from index\n",
    "        yearly_summary = pd.DataFrame()\n",
    "        yearly_summary['NDWI'] = df.NDWI.resample('Y').mean()\n",
    "\n",
    "        yearly_summary['Time'] = yearly_summary.index\n",
    "        print(yearly_summary.head())\n",
    "\n",
    "\n",
    "        # Create Line Chart\n",
    "        fig = px.line(yearly_summary,\n",
    "                      x = yearly_summary['Time'],\n",
    "                      y = yearly_summary['NDWI'])\n",
    "\n",
    "        # Fig Update & Set Title\n",
    "        fig.update_layout(title_text=\"Yearly Mean NDWI Values\")\n",
    "        fig.update_traces(overwrite=True)\n",
    "\n",
    "\n",
    "        #return \"start: {}, end: {}\".format(start_date_string, end_date_string) \n",
    "        return [\n",
    "            dcc.Graph(\n",
    "                id=column,\n",
    "                figure = fig\n",
    "            )\n",
    "            # check if column exists - user may have deleted it\n",
    "            # If `column.deletable=False`, then you don't\n",
    "            # need to do this check.\n",
    "            for column in [\"NDWI\"] if column in yearly_summary\n",
    "        ]\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    app.run_server(debug=False, port=8150)\n",
    "    #app.run_server(debug=True, port=8888)\n",
    "    \n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
